#pragma once
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "../comm/commfun.hpp"
#include "../comm/log.hpp"

using namespace std;
using namespace ns_commfunc;

namespace ns_compile
{
    class Compile
    {
    private:
    public:
        Compile()
        {
        }

        ~Compile()
        {
        }

        /*
            @return val: 编译结果是否成功
            @pragma    : 文件名
        */
        static bool compile(const string filename)
        {
            int id = fork();
            if(id < 0)
            {
                Log(Error, "子进程创建失败");
                return false;
            } 
            else if(id == 0)
            {
                // 子进程

                //重定向
                umask(0);
                int error_fd = open(PathUtil::filepath_stderr(filename).c_str(), O_CREAT|O_WRONLY, 0644);
                if(error_fd < 0) 
                {
                    Log(Error, "stderr文件创建失败");
                    exit(1);
                }
                dup2(error_fd, 2);

                //程序替换， 编译代码
                execlp("g++", "g++", "-o", PathUtil::filepath_exe(filename).c_str(), \
                PathUtil::filepath_src(filename).c_str(), "-D", "COMPILER_ONLINE", "-std=c++11", nullptr);

                //到这里g++就是替换执行失败
                Log(Error, "g++执行失败");
                exit(2);
            }
            else
            {
                waitpid(id, nullptr, 0);
                if(FileUtil::Isexist_file(PathUtil::filepath_exe(filename)))
                {
                    Log(Info, "编译成功");
                    return true;
                }                  
            }

            Log(Error, "编译失败");
            return false;
        }
    };


}
